import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.logging.Logger;
import java.util.logging.Level;

/**
 * 代理处理器类
 * 实现对add方法的校验和日志记录功能
 */
public class YiXinZhiProxyHandler implements InvocationHandler {
    // 增加成员变量：目标对象
    private Calculator calculator;

    // 统计信息：记录方法调用次数
    private int callCount = 0;

    // 统计信息：记录校验失败的次数
    private int validationFailureCount = 0;

    // 日志记录器
    private static final Logger logger = Logger.getLogger(YiXinZhiProxyHandler.class.getName());

    // 构建带参数的构造方法
    public YiXinZhiProxyHandler(Calculator calculator) {
        // 为成员变量赋值
        this.calculator = calculator;
        logger.info("代理处理器初始化完成");
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 增加调用计数
        callCount++;

        // 记录方法调用开始
        logger.info("========== 方法调用开始 ==========");
        logger.info("调用方法: " + method.getName());
        logger.info("调用次数: " + callCount);

        // 根据参数数组 args 获取方法的参数
        int a = (int) args[0];
        int b = (int) args[1];

        logger.info("参数 a = " + a);
        logger.info("参数 b = " + b);

        // 校验1：检查参数是否有负数
        if (a < 0 || b < 0) {
            validationFailureCount++;
            logger.warning("校验失败：参数包含负数！a=" + a + ", b=" + b);
            logger.info("========== 方法调用结束 ==========");
            return -1;
        }

        // 校验2：检查结果是否会超过int的最大值
        // 使用long类型来检查溢出
        long resultLong = (long) a + (long) b;
        if (resultLong > Integer.MAX_VALUE) {
            validationFailureCount++;
            logger.warning("校验失败：结果超过int最大值！a=" + a + ", b=" + b + ", 预期结果=" + resultLong);
            logger.info("========== 方法调用结束 ==========");
            return -2;
        }

        // 校验通过，调用目标对象的方法
        logger.info("参数校验通过，调用目标方法");
        int result = calculator.add(a, b);

        logger.info("方法执行结果: " + result);
        logger.info("========== 方法调用结束 ==========");

        return result;
    }

    /**
     * 获取方法调用统计信息
     * 
     * @return 统计信息字符串
     */
    public String getStatistics() {
        return String.format("统计信息 - 总调用次数: %d, 校验失败次数: %d, 成功率: %.2f%%",
                callCount, validationFailureCount,
                callCount > 0 ? (double) (callCount - validationFailureCount) / callCount * 100 : 0);
    }

    /**
     * 获取调用次数
     * 
     * @return 调用次数
     */
    public int getCallCount() {
        return callCount;
    }

    /**
     * 获取校验失败次数
     * 
     * @return 校验失败次数
     */
    public int getValidationFailureCount() {
        return validationFailureCount;
    }
}
